package com.examination.client.interceptor;


import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.http.HttpStatus;
import com.auth0.jwt.interfaces.Claim;
import com.examination.client.annotation.PassToken;
import com.examination.client.entity.UserInfo;
import com.examination.client.enums.BusinessExceptionEnum;
import com.examination.client.exception.BusinessException;
import com.examination.client.service.IUserInfoService;
import com.examination.client.util.JsonUtils;
import com.examination.client.util.JwtTokenUtil;
import com.examination.client.util.UserInfoUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Objects;


/**
 * @author: XiaoDong
 * @date: 2021-10-23 14:42
 * @description: c端管理拦截器
 */
@Slf4j
public class AuthenticationInterceptor implements HandlerInterceptor {
    @Resource
    IUserInfoService userInfoService;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws BusinessException {
        String token = request.getHeader("token");
        String requestURI = request.getRequestURI();
        if (requestURI.contains("pay") && !requestURI.contains("pushOrder") && !requestURI.contains("/callback/notify") ) {
            return true;
        }
        if (!(object instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) object;
        Method method = handlerMethod.getMethod();
        if (method.isAnnotationPresent(PassToken.class)) {
            PassToken passToken = method.getAnnotation(PassToken.class);
            if (passToken.required()) {
                return true;
            }
        }

        if (token == null) {
            log.info("token 为空:{}",token);
            throw new BusinessException(BusinessExceptionEnum.AGAIN_LOGIN.code,BusinessExceptionEnum.AGAIN_LOGIN.msg);
        }

        if (!JwtTokenUtil.verifyToken(token)) {
            log.info("token 验证失败:{}",token);
            response.setStatus(HttpStatus.HTTP_UNAUTHORIZED);
            throw new BusinessException(BusinessExceptionEnum.TOKEN_INVALID.code,BusinessExceptionEnum.TOKEN_INVALID.msg);
        }

        //防止后台修改用户关联的站点 导致信息不一致
        Integer userId = JwtTokenUtil.getClaims(token).get().get("userId").asInt();
        log.info("根据token解析用户uid:{}", JsonUtils.toJson(userId));
        UserInfo userInfo = userInfoService.getById(userId);
        if(Objects.isNull(userInfo)){
            log.info("根据token解析用户信息:{}", JsonUtils.toJson(userInfo));
            throw new BusinessException(BusinessExceptionEnum.USER_INVALID.code,BusinessExceptionEnum.USER_INVALID.msg);
        }

        UserInfoUtil.setUser(token,userInfo);
        return true;

    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    }
}
